package com.ysstech.codegen.util;

import com.ysstech.codegen.entity.ClassInfo;
import com.ysstech.codegen.entity.ConfigInfo;
import com.ysstech.codegen.entity.FieldInfo;
import com.ysstech.codegen.entity.ParamInfo;
import com.ysstech.codegen.enumeration.FileExtEnum;

import com.alibaba.fastjson.JSON;
import kotlin.text.*;
import lombok.extern.slf4j.Slf4j;

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class SpringCodeGenUtil {

    public static String getGenFileName(String label, String text, String fileExt) {
        String fileName = label;
        String pattern = null;
        Set<RegexOption> options = new HashSet<>();
        options.add(RegexOption.MULTILINE);
        Regex regex = null;

        FileExtEnum fileExtEnum = FileExtEnum.getFileExtEnum(fileExt);
        fileExtEnum = fileExtEnum == null?  FileExtEnum.TXT : fileExtEnum;
        switch (fileExtEnum) {
            case JAVA:
                pattern = "public[\\s]+(class|interface)[\\s]+([a-zA-Z0-9]+)[\\s]+[\\s\\S]*?\\{";
                regex = new Regex(pattern,options);
                String className = regex.find(text,0).getGroupValues().get(2);
                fileName = className;
                break;
            case XML:
                pattern = "<mapper namespace=\"[\\.a-zA-Z0-9]+\\.([a-zA-Z0-9]+)\">";
                regex = new Regex(pattern,options);
                String mapperName = regex.find(text,0).getGroupValues().get(1);
                fileName = mapperName;
            default:
                break;
        }

        fileName = fileName+fileExtEnum.getExt();
        return fileName;
    }


    public static void saveCodeText(String dirPath, String label, String text,String subPackage, String fileExt) throws Exception {
        String[] subDirs = subPackage.split("\\.");
        String currentDir = dirPath;
        for (String subDir : subDirs) {
            currentDir = currentDir+"/"+subDir;
            FileUtils.makeDir(currentDir);
        }
        String path = currentDir+String.format("/%s", getGenFileName(label,text,fileExt));
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(path));
        dos.write(text.getBytes("UTF-8"));
        dos.flush();
        dos.close();
    }

    public static ConfigInfo getConfigInfo(InputStream inputStream) throws Exception {
        ConfigInfo configInfo = JSON.parseObject(inputStream,ConfigInfo.class);
        return configInfo;
    }

    public static ClassInfo processClassInfo(ClassInfo classInfo,ParamInfo paramInfo) {
        if (paramInfo.getBaseEntityFields() != null) {
            List<FieldInfo> fieldInfos = classInfo.getFieldList();
            fieldInfos = fieldInfos.stream().filter(fieldInfo -> !paramInfo.getBaseEntityFields().contains(fieldInfo.getFieldName())).collect(Collectors.toList());
            classInfo.setSubEntityFieldList(fieldInfos);
        }

        if (paramInfo.getAuditFields() != null) {
            List<FieldInfo> fieldInfos = classInfo.getFieldList();
            fieldInfos = fieldInfos.stream().filter(fieldInfo -> !paramInfo.getAuditFields().contains(fieldInfo.getFieldName())).collect(Collectors.toList());
            classInfo.setAuditFieldList(fieldInfos);
        }

        if (paramInfo.getBaseRepFields() != null) {
            List<FieldInfo> fieldInfos = classInfo.getFieldList();
            fieldInfos = fieldInfos.stream().filter(fieldInfo -> !paramInfo.getBaseRepFields().contains(fieldInfo.getFieldName())).collect(Collectors.toList());
            classInfo.setSubRepFieldList(fieldInfos);
        }

        if (paramInfo.getBaseReqFields() != null) {
            List<FieldInfo> fieldInfos = classInfo.getFieldList();
            fieldInfos = fieldInfos.stream().filter(fieldInfo -> !paramInfo.getBaseReqFields().contains(fieldInfo.getFieldName())).collect(Collectors.toList());
            classInfo.setSubReqFieldList(fieldInfos);
        }

        return classInfo;
    }

}
